# generate can message struct 
# the format looks like the following:
# struct message_name {
#   signal type signal_name;
#   ...
# };

# struct nodename {
#  message_type message_name;
#  ...
# };
# the message_name is lowercase of message_type

import json

def gen_struct(dp, logging):
    signal_type_map = {
        "uint8": "uint32_t",
        "uint16": "uint32_t",
        "uint32": "uint32_t",
        "uint64": "uint64_t",
        "int8": "int32_t",
        "int16": "int32_t",
        "int32": "int32_t",
        "int64": "int64_t",
        "float": "float",
        "double": "double",
        "bool": "bool",
        "string": "std::string"
    }
    
    for node in dp.config.can_node_list:
        node_data = {
            "node_name": node['node_name'],
            "messages": []
        }
        
        struct_code = ""
        struct_code += "#pragma once\n\n"
        struct_code += "#include <string>\n"
        struct_code += "#include <stdint.h>\n\n"
        for message in dp.data:
            if message.can_node == node['node_name']:
                struct_code += f"struct {message.name}_MSG {{\n"
                
                for signal in message.signals:
                    signal_type = signal_type_map[signal.signal_type]
                    if signal.min.startswith('-'):
                        # print(f"special struct info: {signal.name}")
                        signal_type = signal_type_map.get(signal.signal_type.replace('u', ''), None)
                    else:
                        signal_type = signal_type_map.get(signal.signal_type, None)

                    if signal_type:
                        struct_code += f"  {signal_type} {signal.name};\n"
                    else:
                        logging.error(f"Unknown signal type: {signal['signal_type']}, not found in type_mapping")

                struct_code += "};\n\n"

        # Write the generated struct to a file
        with open(f'output/can_node_{node["node_name"]}.h', 'w') as file:
            file.write(struct_code)
